﻿// HSS.Interlink.MouseClickManager.cs
// ----------------------------------------------------------------------------
// Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.html)
// ----------------------------------------------------------------------------
// HighSpeed-Solutions, LLC
// Copyright (c) 2001-2010
// ----------------------------------------------------------------------------
// File:       MouseClickManager.cs
// Author:     HSS\gbanta
// Created:    07/16/2011
// Modified:   07/22/2011
// ----------------------------------------------------------------------------
namespace HSS.Interlink
{
	#region Using Directives
	using System.Threading;
	using System.Windows.Controls;
	using System.Windows.Input;
	#endregion

	#region MouseClickManager
	/// <summary>
	/// MouseClickManager for capturing Double Clicks of a control
	/// </summary>
	public sealed class MouseClickManager
	{
		#region Events
		/// <summary>
		/// Event fired when the Owner Object is clicked.
		/// </summary>
		public event MouseButtonEventHandler Click;
		/// <summary>
		/// Called when [click].
		/// </summary>
		/// <param name="sender">The sender.</param>
		/// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
		private void OnClick(object sender, MouseButtonEventArgs e)
		{
			MouseButtonEventHandler handler = Click;
			if (handler != null)
				this.Control.Dispatcher.BeginInvoke(handler, sender, e);
		}
		/// <summary>
		/// Event fired when the Owner Object is double clicked.
		/// </summary>
		public event MouseButtonEventHandler DoubleClick;
		/// <summary>
		/// Called when [double click].
		/// </summary>
		/// <param name="sender">The sender.</param>
		/// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
		private void OnDoubleClick(object sender, MouseButtonEventArgs e)
		{
			MouseButtonEventHandler handler = DoubleClick;
			if (handler != null)
				handler(sender, e);
		}
		#endregion

		#region Constructor
		/// <summary>
		/// Initializes a new instance of the <see cref="MouseClickManager"/> class with a default Timeout of 300ms.
		/// </summary>
		/// <param name="control">The control.</param>
		public MouseClickManager(Control control)
			: this(control, 300)
		{
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="MouseClickManager"/> class.
		/// </summary>
		/// <param name="control">The control.</param>
		/// <param name="timeout">The timeout between a new click versus a double click</param>
		public MouseClickManager(Control control, int timeout)
		{
			this.Clicked = false;
			this.Control = control;
			this.Timeout = timeout;
		}
		#endregion

		#region Properties
		/// <summary>
		/// Gets or sets a value indicating whether this <see cref="MouseClickManager"/> is clicked.
		/// </summary>
		/// <value><c>true</c> if clicked; otherwise, <c>false</c>.</value>
		private bool Clicked { get; set; }
		/// <summary>
		/// Gets or sets the control.
		/// </summary>
		/// <value>The control.</value>
		public Control Control { get; set; }
		/// <summary>
		/// Gets or sets the timeout which indicates a DoubelClick or SingleClick.
		/// </summary>
		/// <value>The timeout.</value>
		public int Timeout { get; set; }
		#endregion

		#region Event Handlers
		/// <summary>
		/// Handles the click.
		/// </summary>
		/// <param name="sender">The sender.</param>
		/// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
		public void HandleClick(object sender, MouseButtonEventArgs e)
		{
			lock (this)
			{
				if (this.Clicked)
				{
					this.Clicked = false;
					OnDoubleClick(sender, e);
				}
				else
				{
					this.Clicked = true;
					new Thread(ResetThread).Start(e);
				}
			}
		}
		/// <summary>
		/// Resets the thread.
		/// </summary>
		/// <param name="state">The state.</param>
		private void ResetThread(object state)
		{
			Thread.Sleep(this.Timeout);

			lock (this)
			{
				if (this.Clicked)
				{
					this.Clicked = false;
					OnClick(this, (MouseButtonEventArgs)state);
				}
			}
		}


		#endregion
	}
	#endregion
}